package xyz.bali16.application.security;

import cn.hutool.core.util.StrUtil;

import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import xyz.bali16.application.config.prop.AuthProp;
import xyz.bali16.application.security.exception.CustomWebResponseExceptionTranslator;
import xyz.bali16.application.security.model.CustomTokenEnhancer;
import xyz.bali16.application.service.UserService;

import javax.sql.DataSource;
import java.util.Arrays;


@Configuration
@EnableAuthorizationServer
@AllArgsConstructor
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private final AuthenticationManager authenticationManager;
    private final UserService userService;

    private final AuthProp authProp;
    private final DataSource dataSource;
    @Autowired
    private CustomTokenEnhancer tokenEnhancer;
    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;
    @Autowired
    private TokenStore tokenStore;
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetails());
    }



    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        //tokenEnhancerChain.setTokenEnhancers(
        //        Arrays.asList(tokenEnhancer(), accessTokenConverter()));

        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer, accessTokenConverter));
        endpoints.tokenEnhancer(tokenEnhancerChain);

        endpoints
                //.tokenStore(tokenStore())
                //.accessTokenConverter(accessTokenConverter())
                //.tokenEnhancer(tokenEnhancer())
                //.tokenEnhancer(jwtTokenEnhancer())
                // 用户管理
                .userDetailsService(userService)
                // 启用OAuth管理
                .authenticationManager(authenticationManager)
                .exceptionTranslator(new CustomWebResponseExceptionTranslator())
                // 接收GET和POST
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
                // 添加令牌增强器

    }

    //
    //@Override
    //public void configure(AuthorizationServerSecurityConfigurer security) {
    //    security.tokenKeyAccess("isAuthenticated()") //获取token
    //            .checkTokenAccess("isAuthenticated()") //验证token
    //            .allowFormAuthenticationForClients();//表单认证申请token
    //}
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
        oauthServer.allowFormAuthenticationForClients();
    }

    @Bean
    public ClientDetailsService clientDetails() {
        return new JdbcClientDetailsService(dataSource);
    }

    //@Override
    //public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    //    clients.inMemory().withClient("user")
    //            .secret(passwordEncoder.encode("123456"))   //需使用passwordEncoder加密
    //            .authorizedGrantTypes("password","refresh_token")
    //            .accessTokenValiditySeconds(3000)           //token的超时时间
    //            .scopes("user");  //客户端认证scope，可任意设置
    //}

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }

    //@Bean
    //@Primary
    //public DefaultTokenServices tokenServices() {
    //    DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    //    defaultTokenServices.setTokenStore(tokenStore());
    //    defaultTokenServices.setSupportRefreshToken(true);
    //    return defaultTokenServices;
    //}

    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        //tokenServices.setClientDetailsService(clientDetailsService);
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setTokenStore(tokenStore);
        // 有效期10秒
        tokenServices.setAccessTokenValiditySeconds(10);
        // 刷新令牌默认有效期3天
        tokenServices.setRefreshTokenValiditySeconds(10);
        // 配置token增强使用jwt
        TokenEnhancerChain chain = new TokenEnhancerChain();
        chain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
        tokenServices.setTokenEnhancer(chain);
        return tokenServices;
    }

}
